// 1. 计算元组类型的长度
type LengthOfTuple<T> = T extends any[] ? T['length'] : never
type LA2 = LengthOfTuple<['B', 'F', 'E']> // 3
type LB2 = LengthOfTuple<[]> // 0

// 2. 得到元组类型中的第一个元素
type FirstItem<T extends any[]> = T extends [infer A, ...infer B] ? A : never
type FA2 = FirstItem<[string, number, boolean]> // string
type FB2 = FirstItem<['B', 'F', 'E']> // 'B'

// 3. 得到元组类型中的最后一个元素
type LastItem<T extends any[]> = T extends [...infer L, infer R] ? R : never
type LAL1 = LastItem<[string, number, boolean]> // boolean
type LBL1 = LastItem<['B', 'F', 'E']> // 'E'
type LCL1 = LastItem<[]> // never

// 4. 移除元组类型中的第一个类型
type Shift<T extends any[]> = T extends [infer L, ...infer R] ? R : T
type SA = Shift<[1, 2, 3]> // [2,3]
type SB = Shift<[1]> // []
type SC = Shift<[]> // []

// 5. 在元组类型T中添加新的类型I
// type Flat<T> = T extends [...infer M] ? M : [T]

type Push<T extends any[], K> = [...T, ...Flat<K>]
type PA = Push<[1, 2, 3], 4> // [1,2,3,4]
type PB = Push<[1], 2> // [1, 2]

type D = Push<[1, 2, 3], [4, 5]> // [1,2,3,4,5]
type E = Push<[1, 2, 3], [string, number]> // [1,2,3,string,number]

type Flat1 = Flat<[1, 2, 3]> // [1,2,3]
type Flat2 = Flat<1> // [1]

// 6. 反转元组
type ReverseTuple<T extends any[], Prev extends any[] = []> = T extends [...infer L, infer R] ? ReverseTuple<L, [...Prev, R]> : Prev
type RA = ReverseTuple<[string, number, boolean]> // [boolean, number, string]
type RB = ReverseTuple<[1, 2, 3]> // [3,2,1]
type RC = ReverseTuple<[]> // []

// 7. 拍平元组

type Flat<T> = T extends [infer L, ...infer R] ?
  [...(L extends any[] ? Flat<L> : [L]), ...Flat<R>] : T

type FA = Flat<[1, 2, 3]> // [1,2,3]
type FB = Flat<[1, [2, 3], [4, [5, [6]]]]> // [1,2,3,4,5,6]
type FC = Flat<[]> // []
type FD = Flat<[1]> // [1]

// 8. 复制类型T为C个元素的元组类型
type Repeat<T, K, Prev extends any[] = []> = K extends Prev['length'] ? Prev : Repeat<T, K, [...Prev, T]>

type RA1 = Repeat<number, 3> // [number, number, number]
type RB1 = Repeat<string, 2> // [string, string]
type RC1 = Repeat<1, 1> // [1]
type RD = Repeat<0, 0> // []

// 9. 保留元组类型T中的A类型
type Filter<T extends any[], K, Prev extends any[] = []> = T extends [infer L, ...infer R] ?
  Filter<R, K, [...Prev, ...([L] extends [K] ? [L] : [])]> : Prev

type FA1 = Filter<[1, 'BFE', 2, true, 'dev'], number> // [1, 2]
type FB1 = Filter<[1, 'BFE', 2, true, 'dev'], string> // ['BFE', 'dev']
type FC1 = Filter<[1, 'BFE', 2, any, 'dev'], string> // ['BFE', any, 'dev']

// 10. 找出E类型在元组类型T中的下标
type Equal<T, K> = [T] extends [K] ? [K] extends [T] ? (keyof T extends keyof K ? keyof K extends keyof T ? true : false : false) : false : false;

type FindIndex<A, T> = A extends [...infer L, infer R] ? Equal<R, T> extends true ? L['length'] : FindIndex<L, T> : never
type EA = [any, never, 1, '2', true]
type EB = FindIndex<EA, 1> // 2
type EC = FindIndex<EA, '2'> // never

type index1 = FindIndex<[1, string, 2, 3, 5], string>
type index2 = FindIndex<[1, 2, string, 3, 5], string>
type index3 = FindIndex<[1, 2, 3, string, 5], string>
type index4 = FindIndex<[1, 2, 3, 5, string], string>

// 11. 元组类型转换为枚举类型
type TupleToEnum<T extends string[], K = false> = {
  readonly [k in T[number]]: K extends true ? FindIndex<T, k> : k
}
// 默认情况下，枚举对象中的值就是元素中某个类型的字面量类型
type Ta1 = TupleToEnum<["MacOS", "Windows", "Linux"]>
// -> { readonly MacOS: "MacOS", readonly Windows: "Windows", readonly Linux: "Linux" }

// 如果传递了第二个参数为true，则枚举对象中值的类型就是元素类型中某个元素在元组中的index索引，也就是数字字面量类型
type Ta2 = TupleToEnum<["MacOS", "Windows", "Linux"], true>
// -> { readonly MacOS: 0, readonly Windows: 1, readonly Linux: 2 }


// 12. 截取元组中的部分元素
type Slice<
  T extends any[],
  S extends number = 0, // 开始位置
  E extends number = T['length'],
  ST extends any[] = [],
  ET extends any[] = [],
  Prev extends any[] = []
  > = T extends [infer L, ...infer R]
  ? S extends ST['length']
  ? E extends ET['length']
  ? [...Prev, L]
  : Slice<R, S, E, ST, [...ET, null], [...Prev, L]>
  : Slice<R, S, E, [...ST, null], [...ET, null], Prev>
  : Prev

type SA1 = Slice<[any, never, 1, '2', true, boolean], 0, 2>          // [any,never,1]                    从第0个位置开始，保留到第2个位置的元素类型
type SA2 = Slice<[any, never, 1, '2', true, boolean], 1, 3>          // [never,1,'2']                    从第1个位置开始，保留到第3个位置的元素类型
type SA3 = Slice<[any, never, 1, '2', true, boolean], 1, 2>          // [never,1]                        从第1个位置开始，保留到第2个位置的元素类型
type SA4 = Slice<[any, never, 1, '2', true, boolean], 2>             // [1,'2',true,boolean]             从第2个位置开始，保留后面所有元素类型
type SA5 = Slice<[any], 2>                                           // []                               从第2个位置开始，保留后面所有元素类型
type SA6 = Slice<[], 0>


// 13. 删除并且替换部分元素
type Splice<
  T extends any[],
  S extends number = 0, // 开始位置
  E extends number = 0,
  I extends any[] = [], // 要插入的元素
  ST extends any[] = [],
  ET extends any[] = [],
  Prev extends any[] = []
  > = T extends [infer L, ...infer R]
  ? S extends ST['length']
  ? E extends ET['length']
  ? [...Prev, ...I, L, ...R]
  : Splice<R, S, E, I, ST, [...ET, null], [...Prev]>
  : Splice<R, S, E, I, [...ST, null], ET, [...Prev, L]>
  : Prev
type SA10 = Splice<[string, number, boolean, null, undefined, never], 0, 2>                   // [boolean,null,undefined,never]               从第0开始删除，删除2个元素
type SA11 = Splice<[string, number, boolean, null, undefined, never], 1, 3>                   // [string,undefined,never]                     从第1开始删除，删除3个元素
type SA12 = Splice<[string, number, boolean, null, undefined, never], 1, 2, [1, 2, 3]>        // [string,1,2,3,null,undefined,never]          从第1开始删除，删除2个元素，替换为另外三个元素1,2,3




type w = any extends number ? 1 : 2// 1|2  // 分发
type w1 = any extends string ? 1 : 2 // 1|2
type w2 = string extends any ? 1 : 2 // 1

type Type<T> = T extends number ? 1 : 2

type w3 = [any] extends number ? 1 : 2 // 2
type w4 = Type<any> // 1|2
type w5 = Type<number | string> // 2|1
type w6 = number | string extends number ? 1 : 2 // 2